www.gusucode.com > Non-photorealistic Camera工具箱源码matlab程序 > Non-photorealistic Camera/NPC.m

    function NPC(up_img,right_img,down_img,left_img,dest_folder)
%NPC: implementation of Non-photorealistic Camera 04. The function finds
%the depth edges of foreground object that was captured using 4 different
%flashes: up, right, down, and left respectively. The 4 images should be
%captured using a tripod setup. The result is a non-photorealistic
%image that is generated based on the extracted depth edges. The output
%images are saved in the "dest_folder".

%Citation:
%Raskar, Ramesh, et al. "Non-photorealistic camera: depth edge detection
%and stylized rendering using multi-flash imaging." ACM transactions on
%graphics (TOG). Vol. 23. No. 3. ACM, 2004.

%Input:
%   -up_img: the up image (captured using the up flash)
%   -right_img: the right image
%   -down_img: the down image
%   -left_img: the left image
%   -dest_folder: the destination folder that is used to save the output
%   images

%Usage:
%NPC(u,r,d,l,'save');

%Author: Mahmoud Afifi - York University
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%

if exist(dest_folder,'dir')==0
    mkdir(dest_folder);
end

if size(up_img,3)>1
    colored=1;
else
    colored=0;
end

display('Extracting depth edges...');

%convert images to grayscale
if colored==1
    gu=double(rgb2gray(up_img));
    gr=double(rgb2gray(right_img));
    gd=double(rgb2gray(down_img));
    gl=double(rgb2gray(left_img));
else
    gu=double(up_img);
    gr=double(right_img);
    gd=double(down_img);
    gl=double(left_img);
end

%remove specular regions
[gu,gr,gd,gl]=removeSpecRegions(gu,gr,gd,gl);

%get max image
I_max=max(max(gu,gr),max(gd,gl));

%compute ratio images
ru=(gu+1)./(I_max+1);
rr=(gr+1)./(I_max+1);
rd=(gd-+1)./(I_max+1);
rl=(gl+1)./(I_max+1);


%detect edges
fx = fspecial('Prewitt'); %try 'Prewitt'
fy = fx';
edu = imfilter(ru,fx);
edr = imfilter(rr,fy);
edd = imfilter(rd,fx);
edl = imfilter(rl,fy);


%calculate edge transitions
edu = edu.*(edu>0); %keep only first negative transition (going from top to bottom)
edr = abs(edr.*(edr<0)); %keep only second negative transition (going from left to right)
edd = abs(edd.*(edd<0)); %keep only second negative transition (going from top to bottom)
edl = edl.*(edl>0); %keep only first negative transition (going from left to right)
mask_all=max(max(edu,edr),max(edd,edl)); %combine all edges together

%remove dots from mask_all
% 
% %(skip it (line 87-91) in the person case, gives more better results)

%clean filters
se = offsetstrel('ball',2,2);
ero=imerode(mask_all,se); %erode the mask to remove small objectgs
ero=mat2gray(ero); %normalize it
mask_all=mask_all.*(bwareaopen(ero>0.1,50,8)); %remove small dots (again)
mask_all=medfilt2(mask_all,[3,3]); %third level of filtering
edges=(mask_all)>0.25; %convert to bw

%show images

%original images
figure('units','normalized','outerposition',[0 0 1 1]) %full screen
subplot(2,2,1);
imshow(up_img);
title('Up image');
subplot(2,2,2);
imshow(right_img);
title('Right image');
subplot(2,2,3);
imshow(down_img);
title('Down image');
subplot(2,2,4);
imshow(left_img);
title('Left image');
axes('Position',[0 0 1 1],'Xlim',[0 1],'Ylim',[0 1],'Box','off',...
    'Visible','off','Units','normalized', 'clipping' , 'off');
%report squared reconstruction error
t=text(0.5, 1,'Original images','HorizontalAlignment',...
    'center','VerticalAlignment', 'top');
t.FontSize = 15;

%edges
%original images
figure('units','normalized','outerposition',[0 0 1 1]) %full screen
subplot(2,2,1);
imshow(1-edu,[]);
title('Up edges');
subplot(2,2,2);
imshow(1-edr,[]);
title('Right edges');
subplot(2,2,3);
imshow(1-edd,[]);
title('Down edges');
subplot(2,2,4);
imshow(1-edl,[]);
title('Left edges');
axes('Position',[0 0 1 1],'Xlim',[0 1],'Ylim',[0 1],'Box','off',...
    'Visible','off','Units','normalized', 'clipping' , 'off');
%report squared reconstruction error
t=text(0.5, 1,'Edges images','HorizontalAlignment',...
    'center','VerticalAlignment', 'top');
t.FontSize = 15;

%show mask all (before cleaning)
figure;
imshow(mask_all,[]);
title('Max edges')

%show final edge mask (after cleaning)
figure;
imshow(1-edges,[]);
title('Depth edges')
imwrite(1-edges,fullfile(dest_folder,'edge-mask.jpg'));


%% NPR image

display('Generating stylized images...');

a=0.3;
lambda=double(edges); %make depth edges =1
lambda(mask_all<0.9 & mask_all>0.1)=a; %make texture edges = a
lambda(lambda==0)=0.2; %values for featureless pixels
lambda=reshape(lambda,size(edges)); %reshape it
lambda=lambda+1.3*edges;

%get colored target image without shadows
if colored==1
  %  T=up_img; %initialize it with any one of input images
    T(:,:,1)=max(max(up_img(:,:,1),down_img(:,:,1)),max(left_img(:,:,1),...
        right_img(:,:,1)));
    T(:,:,2)=max(max(up_img(:,:,2),down_img(:,:,2)),max(left_img(:,:,2),...
        right_img(:,:,2)));
    T(:,:,3)=max(max(up_img(:,:,3),down_img(:,:,3)),max(left_img(:,:,3),...
        right_img(:,:,3)));
else
    T=I_max;
end



%now apply poisson image editing using T (target image) M (mask) and L
%(laplacian of source image).
display('Applying Poisson image editing...');
Tt=imresize(T,[300,300]); %resize to speed up Poisson blending
Ll=imresize(lambda,[300,300]); %resize to speed up Poisson blending
stylized_img_=PIE(Tt,Ll,1-colored); %Poisson blending
stylized_img_=imresize(stylized_img_,[size(T,1),size(T,2)]); %resize to original size
stylized_img_=uint8(stylized_img_*255); %from double to uint8
stylized_img_=RGBHistMatch(stylized_img_,T); %histogram matching
e=uint8(cat(3,edges,edges,edges));  %prepare edges to be added 
se = offsetstrel('ball',2,2); %change the thickness of edges
edilate=imdilate(e,se);
stylized_img=stylized_img_.*(1-edilate);
figure;
imshow(stylized_img); %show the final stylized image
title('Synthetic image');
imwrite(stylized_img,fullfile(dest_folder,'stylized_imgB.jpg')); %save it

%use white edges
stylized_img=stylized_img_+(255*e);
figure;
imshow(stylized_img); %show the final stylized image
title('Synthetic image');
imwrite(stylized_img,fullfile(dest_folder,'stylized_imgW.jpg')); %save it

end